using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using UtopianGame.graphics;
using UtopianGame.graphics.menu;

namespace UtopianGame
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        const int MAX_TURN_COUNT = 50;

        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        ButtonState prevLeftButtonState = ButtonState.Released;
        ButtonState currentLeftButtonState = ButtonState.Released;
        int width;
        int progress;
        int goodwill;
        int population;
        double costOfLiving;
        double healthRate;
        double crimeRate;
        double literacyRate;
        double time;
        Texture2D ProgressBar;
       

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
          
            //Sets the window size.
            graphics.PreferredBackBufferWidth = 1000;
            graphics.PreferredBackBufferHeight = 600;
            graphics.ApplyChanges();

            //Make the mouse cursor visible
            this.IsMouseVisible = true;

            //Initialize the Nation.
            Nation.Init();

            //Initialize the GlobalDataHolder
            GlobalDataHolder.init(this.Content);

            //Initialize the GameFlowSystem.
            GameFlowSystem.startGame();

            //Initialize progress bar
            width = GraphicsDevice.Viewport.Width;

            //Lay out the prototype menu
            //rightSideAlignment and bottomSideAlignment is a variable used to determine where to position menu buttons which are supposed
            //to be, when aligned to edges that aren't the top or left.
            int rightSideAlignment = 0;
            int bottomSideAlignment = 0;
            GlobalDataHolder.addGraphicalObject(new BlueSquareGraphicalObject(this.Content), 1000, 600, 500);
            rightSideAlignment = 1000 - (int)(GlobalDataHolder.baseFont.MeasureString("Policies").X) - 32;
            GlobalDataHolder.addGraphicalObject(new TextMenuButton(this.Content, "Policies"), rightSideAlignment, 32);
            rightSideAlignment = 1000 - (int)(GlobalDataHolder.baseFont.MeasureString("Infrastructure").X) - 32;
            bottomSideAlignment = 600 - (int)(GlobalDataHolder.baseFont.MeasureString("Infrastructure").Y) - 32;
            GlobalDataHolder.addGraphicalObject(new TextMenuButton(this.Content, "Infrastructure"), rightSideAlignment, bottomSideAlignment);
            //creates map
            GlobalDataHolder.addGraphicalObject(new HexagonButton(this.Content, 0), 210, 100);//top left hexagon
            GlobalDataHolder.addGraphicalObject(new HexagonButton(this.Content, 1), 360, 15); //top hexagon
            GlobalDataHolder.addGraphicalObject(new HexagonButton(this.Content, 2), 510, 100);//top right hexagon
            GlobalDataHolder.addGraphicalObject(new HexagonButton(this.Content, 3), 210, 270);//bottom left hexagon
            GlobalDataHolder.addGraphicalObject(new HexagonButton(this.Content, 4), 360, 190);//centre hexagon
            GlobalDataHolder.addGraphicalObject(new HexagonButton(this.Content, 5), 510, 270);//bottom right hexagon
            GlobalDataHolder.addGraphicalObject(new HexagonButton(this.Content, 6), 360, 350);//bottom hexagon
            
            bottomSideAlignment = 600 - (int)(GlobalDataHolder.baseFont.MeasureString("New Turn").Y) - 32;
            GlobalDataHolder.addGraphicalObject(new NewTurnButton(this.Content), 16, bottomSideAlignment, 0);

            base.Initialize();

        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            progress = 0;

            ProgressBar = Content.Load<Texture2D>("ProgressBarFinal");
            // TODO: use this.Content to load your game content here
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {

             progress=GameFlowSystem.GetCurrentTurn();
           
            if (progress < 0) 
            {
                progress = 0;
            }
            if (progress > MAX_TURN_COUNT)
            {
                progress = MAX_TURN_COUNT;
            }

            
            // Allows the game to exit
            if ((GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) || GlobalDataHolder.isGameOver)
            {
                this.Exit();
            }

            // TODO: Add your update logic here
            prevLeftButtonState = currentLeftButtonState;
            currentLeftButtonState = Mouse.GetState().LeftButton;


            if (currentLeftButtonState == ButtonState.Released && prevLeftButtonState == ButtonState.Pressed)
            {
                mouseClick();

            }
            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.WhiteSmoke);

            // TODO: Add your drawing code here


            spriteBatch.Begin();

            spriteBatch.Draw(Content.Load<Texture2D>("blueSquare"),new Rectangle(0,0,1000,600),Color.White);
            
            int turnNumber = GameFlowSystem.GetCurrentTurn();
            //spriteBatch.DrawString(GlobalDataHolder.baseFont, turnNumber, new Microsoft.Xna.Framework.Vector2(490, 350), Color.White);
        
            //spriteBatch.DrawString(GlobalDataHolder.baseFont, "Time:" ,new Microsoft.Xna.Framework.Vector2(10, 50), Color.Black);
            spriteBatch.DrawString(GlobalDataHolder.baseFont, "Turn:"+ turnNumber, new Microsoft.Xna.Framework.Vector2(10, 100), Color.Black);
            spriteBatch.DrawString(GlobalDataHolder.baseFont, "Budget: $"+ Nation.moneyInTreasury, new Microsoft.Xna.Framework.Vector2(10,150), Color.Black);

            spriteBatch.DrawString(GlobalDataHolder.baseFont, "Population:"+ Nation.getPopulationCount(), new Microsoft.Xna.Framework.Vector2(700,150), Color.Black);
            spriteBatch.DrawString(GlobalDataHolder.baseFont, "Health Rate:" + Nation.getAverageHealthIndex() + "%", new Microsoft.Xna.Framework.Vector2(700, 200), Color.Black);
            spriteBatch.DrawString(GlobalDataHolder.baseFont, "Crime Rate:"+ Nation.getAverageCrimeIndex() +"%", new Microsoft.Xna.Framework.Vector2(700, 250), Color.Black);
            spriteBatch.DrawString(GlobalDataHolder.baseFont, "Literacy Rate:"+ Nation.getAverageEducationIndex() +"%" , new Microsoft.Xna.Framework.Vector2(700, 300), Color.Black);
            spriteBatch.DrawString(GlobalDataHolder.baseFont, "Cost Of Living: $"+Nation.getAverageCostOfLiving(), new Microsoft.Xna.Framework.Vector2(700, 350), Color.Black);
            spriteBatch.DrawString(GlobalDataHolder.baseFont, "Average Income: $"+Nation.getAverageIncome(), new Microsoft.Xna.Framework.Vector2(700, 400), Color.Black);
            spriteBatch.DrawString(GlobalDataHolder.baseFont, "People in Poverty: " + Nation.getPovertyCount(), new Microsoft.Xna.Framework.Vector2(700, 450), Color.Black);

            //Negative Progress First
            spriteBatch.Draw(ProgressBar, new Rectangle(this.Window.ClientBounds.Width/2 - ProgressBar.Width/2,550,ProgressBar.Width,44),new Rectangle(0,45,ProgressBar.Width,44),Color.Gray);
            //draw progress level based on current progress
            spriteBatch.Draw(ProgressBar, new Rectangle(this.Window.ClientBounds.Width / 2 - ProgressBar.Width / 2,550,(int)(ProgressBar.Width*((double)progress/MAX_TURN_COUNT)),44), new Rectangle(0, 45,ProgressBar.Width, 44), Color.Red);
            //draw box around health bar
            spriteBatch.Draw(ProgressBar, new Rectangle(this.Window.ClientBounds.Width/ 2 - ProgressBar.Width / 2,550,ProgressBar.Width,44), new Rectangle(0, 0, ProgressBar.Width, 44), Color.White);
            
         //   This loops through graphicalObjectList, and displays every object on it, unless the object is inactive.
            for (int i = 0; i < GlobalDataHolder.graphicalObjectList.Count; i++)
            {
                //The object is only drawn if it is active.
                GraphicalObject objToDraw = GlobalDataHolder.graphicalObjectList.ElementAt(i);
                if (objToDraw.getIsActive() == true)
                {
                    objToDraw.draw(spriteBatch);
                }
            }

            spriteBatch.End();
            
            base.Draw(gameTime);
        }

        /// <summary>
        /// This checks the behavior of each onscreen GraphicalObject when
        /// the mouse is clicked, to see if they should execute code.
        /// </summary>
        protected void mouseClick()
        {
            for (int i = 0; i < GlobalDataHolder.graphicalObjectList.Count; i++)
            {
                GraphicalObject obj = GlobalDataHolder.graphicalObjectList.ElementAt(i);
                if (obj.getClickable() == true && obj.getIsActive() == true)
                {
                    obj.clicked(Mouse.GetState());
                }
            }
        }
    }
}
